package top.zhangjianyong.tools.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import top.zhangjianyong.tools.annotation.Mark;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

@Slf4j
public class AnnotationScanner {

    public static void main(String[] args) {
        String packageName = "top.zhangjianyong.tools"; // 替换为你的包名
        String outputFilePath = "marked_methods.txt"; // 输出文件路径

        List<Method> markedMethods = findMarkedMethods(packageName);
        writeMethodsToFile(markedMethods, outputFilePath);
    }

    private static List<Method> findMarkedMethods(String packageName) {
        List<Method> methods = new ArrayList<>();
        try {
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            assert classLoader != null;
            String path = packageName.replace('.', '/');
            Enumeration<URL> resources = classLoader.getResources(path);
            List<File> dirs = new ArrayList<>();
            while (resources.hasMoreElements()) {
                URL resource = resources.nextElement();
                dirs.add(new File(resource.getFile()));
            }
            for (File directory : dirs) {
                methods.addAll(findMarkedMethods(directory, packageName));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return methods;
    }

    private static List<Method> findMarkedMethods(File directory, String packageName) throws IOException {
        List<Method> methods = new ArrayList<>();
        if (!directory.exists()) {
            return methods;
        }
        File[] files = directory.listFiles();
        assert files != null;
        for (File file : files) {
            if (file.isDirectory()) {
                assert !file.getName().contains(".");
                methods.addAll(findMarkedMethods(file, packageName + "." + file.getName()));
            } else if (file.getName().endsWith(".class")) {
                String className = packageName + '.' + file.getName().substring(0, file.getName().length() - 6);
                try {
                    Class<?> clazz = Class.forName(className);
                    for (Method method : clazz.getDeclaredMethods()) {
                        if (method.isAnnotationPresent(Mark.class)) {
                            methods.add(method);
                        }
                    }
                } catch (ClassNotFoundException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return methods;
    }

    private static void writeMethodsToFile(List<Method> methods, String filePath) {
        try (FileWriter writer = new FileWriter(filePath)) {
            for (Method method : methods) {
                writer.write(method.toString() + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}